package org.jeecg.modules.charge.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baiwang.utility.encrypt.MyAES;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.util.ComUtil;
import org.jeecg.common.util.StringUtils;
import org.jeecg.entity.charge.*;
import org.jeecg.enums.InvoiceTypeEnum;
import org.jeecg.enums.PayModeEnum;
import org.jeecg.enums.charge.InvoiceStatusEnum;
import org.jeecg.modules.charge.entity.BwInvoiceEntity.BlueInvoiceDetailed;
import org.jeecg.modules.charge.entity.BwInvoiceEntity.InvoiceBwConfig;
import org.jeecg.modules.charge.entity.GxInvoiceEntity.*;
import org.jeecg.modules.charge.mapper.ComConfigMapper;
import org.jeecg.modules.charge.service.*;
import org.jeecg.modules.charge.service.impl.ChargeEleinvoiceServiceImpl;
import org.jeecg.modules.charge.vo.GxInvoiceUtils.RequestUtils;
import org.jeecg.modules.charge.vo.GxInvoiceUtils.Sha256Utils;
import org.jeecg.modules.charge.vo.GxInvoiceUtils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
@Api(tags="国信开票接口")
@RestController
@RequestMapping(value = "/api/charge/makeInvoiceGx")
public class ChargeGxInvoiceController {
	/** SLF4J日志 */
	protected static final Logger logger = LoggerFactory.getLogger(ChargeGxInvoiceController.class);

	@Autowired
	private ChargeEleinvoiceServiceImpl eleInvoiceService;
	@Autowired
	private IChargeInvoiceRequestService invoiceReqService;
	@Autowired
	private IChargeInvoiceInfoService invoiceInfoService;
	@Autowired
	private IChargeInvoiceService invoiceService;
	@Autowired
	private IChargeFeeitemService feeItemService;
    @Autowired
    private IChargeBillsService chargeBillsService;
	@Autowired
	private ComConfigMapper comConfigMapper;

	/**
	 * 开具发票
	 */
	@AutoLog(value = "APP开具蓝票接口")
	@ApiOperation(value="APP开具蓝票接口", notes="APP开具蓝票接口")
	@PostMapping(value = "openBlue")
	@ResponseBody
	public boolean openBlue(@RequestBody String req, HttpServletRequest request) throws Exception {
	    logger.info("开始请求开票,开票参数:{}", req);
        ChargeInvoiceRequest invoiceRequest = JSONObject.parseObject(req, ChargeInvoiceRequest.class);
		request.setAttribute("tenantId",invoiceRequest.getTenantId());
        invoiceRequest.setId(String.valueOf(IdWorker.getId()));
        List<String> billIds = null;
		if (StringUtils.isNotEmpty(invoiceRequest.getBillIds())) {
		    billIds = Arrays.asList(invoiceRequest.getBillIds().split(","));
            if (billIds.size() == 0){
                logger.warn("无效的账单={}", invoiceRequest.getBillIds());
                return false;
            }
		    if (StringUtils.isEmpty(invoiceRequest.getRoomId())){
                logger.warn("房间ID为空");
                return false;
            }
		}
		if (StringUtils.isEmpty(invoiceRequest.getOrderNum())) {
		    logger.warn("开具发票订单号为空！");
		    return false;
		}
		InvoiceBwConfig config = comConfigMapper.get(invoiceRequest.getTenantId());
		if(null==config) {
			logger.info("项目暂无对应的配置");
			return false;
		}
		invoiceRequest.setId(String.valueOf(IdWorker.getId()));
		invoiceRequest.setDelFlag("0");
		invoiceRequest.setFplx("0");

		REQUEST_COMMON_FPKJ fpkj = new REQUEST_COMMON_FPKJ();
		// 1-税控盘 2-金税盘 3-UKEY 4-老税控服务器 5-新型税控服务器
		fpkj.setSBLX("4");
		fpkj.setFPQQLSH(ComUtil.createInvoiceSn(config.getProjectCode(), 3));
		// 026 增值税普票(电票) 004 增值税专票(纸票) 028 增值税专票(电票) 007 增值税普票(纸票) 025 增值税普票(卷票)
		fpkj.setFPLXDM("026");
		// 0-蓝字发票；1-红字发票
		fpkj.setKPLX("0");
		// 0：普通征税 1：减按计征 2：差额征税
		fpkj.setZSFS("0");
		fpkj.setXSF_NSRSBH(config.getXsfNsrsbh());
		fpkj.setXSF_MC(config.getXsfMc());
		fpkj.setXSF_DZDH(config.getXsfDzdh());
		fpkj.setXSF_YHZH(config.getXsfYhzh());
        String tel = "";
        String address = "";
        if (StringUtils.isNotEmpty(invoiceRequest.getEin())) {
            // 税号
            String ein = invoiceRequest.getEin().replaceAll(" ", "");
            fpkj.setGMF_NSRSBH(ein);
        }
        if (StringUtils.isNotEmpty(invoiceRequest.getTel()) && this.isPhone(invoiceRequest.getTel())) {
            tel = invoiceRequest.getTel();
            fpkj.setGMF_SJH(tel);
        }
        if (StringUtils.isNotEmpty(invoiceRequest.getEmail())){
            String email = invoiceRequest.getEmail().replaceAll(" ", "");
            if (this.isEmail(email)) fpkj.setGMF_DZYX(email);
        }
        if (StringUtils.isNotEmpty(invoiceRequest.getAccount())) {
            fpkj.setGMF_YHZH(invoiceRequest.getAccount());
        }
        if (StringUtils.isNotEmpty(address)) {
            address = invoiceRequest.getAddress();
        }

		fpkj.setGMF_MC(invoiceRequest.getGmfMc());
		fpkj.setGMF_DZDH(address + " " + tel);
		fpkj.setKPR(config.getKpr());
		fpkj.setSKR(config.getKpr());
		fpkj.setFHR(config.getFhr());
		fpkj.setJSHJ(String.valueOf(new BigDecimal(invoiceRequest.getMoney()).setScale(2, BigDecimal.ROUND_HALF_UP)));
        fpkj.setBZ(invoiceRequest.getRemarks() + "\n" + PayModeEnum.getDesc(invoiceRequest.getPayMode()));

        double hjse = 0.0; // 合计税额
        double hjje = 0.0; // 合计金额
        double sl = 0.0; // 税率
        List<BlueInvoiceDetailed> blueInvoiceList = new ArrayList<BlueInvoiceDetailed>(); //电子发票的详情集合
		// 商品信息
        List<COMMON_FPKJ_XMXX> xmxxList = new ArrayList<>();
		// 无账单 月卡、水电费开票
		if (StringUtils.isEmpty(invoiceRequest.getBillIds())){
            COMMON_FPKJ_XMXX xmxx = new COMMON_FPKJ_XMXX();
            ChargeFeeitem feeItem = feeItemService.getFeeitemById(invoiceRequest.getFeeitemId());
            if (null == feeItem){
                logger.info("无效的收费项==={}", invoiceRequest.getFeeitemId());
                return false;
            }
//            Double rate = (double)eleInvoiceService.getRateByRoomFeeCode(invoiceRequest.getRoomId(), invoiceRequest.getFeeCode());
            sl = (double)feeItem.getTaxRate()/100;
            xmxx.setSL(String.valueOf(sl));
            xmxx.setBY2(feeItem.getId());
            // 0 正常行、1 折扣行、2 被 折扣行
            xmxx.setFPHXZ("0");
            xmxx.setXMSL("1");
            // 不含税金额
            Double realjesum = new BigDecimal(invoiceRequest.getMoney() / (1 + sl))
                    .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            // 不含税单价
            Double realdj = realjesum / Integer.valueOf(xmxx.getXMSL());
            // 税额
            Double se = new BigDecimal(invoiceRequest.getMoney() - realjesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            hjje = realjesum;
            hjse = se;
            xmxx.setXMJE(String.valueOf(realjesum));
            xmxx.setXMDJ(String.valueOf(realdj));
            xmxx.setSE(String.valueOf(se));
            xmxx.setSPBM(feeItem.getMaintenanceCost());
            xmxx.setXMMC(feeItem.getFeeName());
            xmxxList.add(xmxx);
            // 合计金额 税额
            fpkj.setHJJE(String.valueOf(new BigDecimal(hjje).setScale(2, BigDecimal.ROUND_HALF_UP)));
            fpkj.setHJSE(String.valueOf(new BigDecimal(hjse).setScale(2, BigDecimal.ROUND_HALF_UP)));
            fpkj.setCOMMON_FPKJ_XMXX(xmxxList);

            SimpleDateFormat smf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String now = smf.format(new Date());
            // 请求开票的JSON
            JsonRootBean jrb = new JsonRootBean();
            jrb.setREQUEST_COMMON_FPKJ(fpkj);
            String content = JSON.toJSONString(jrb);
            logger.info("发票未加密报文信息========" + jrb);
            content = new BASE64Encoder().encodeBuffer(content.getBytes("UTF-8"));
            content = content.replaceAll("\r\n", "").replaceAll("\n", "");//json的报文不允许有换行，base64会产生。因此此处做去换行处理。
            String contentSha256 = Sha256Utils.SHA256Encrypt(content.getBytes("UTF-8"));
            String contentKey = MyAES.encryptBASE64(MyAES.encrypt(contentSha256.getBytes("UTF-8"), config.getContentPassword())).replaceAll("\r\n", "").replaceAll("\n", "");

            // 发票请求通用报文
            JsonToBean jtb = new JsonToBean();
            jtb.getGlobalInfo().setAppId(config.getAppid());
            jtb.getGlobalInfo().setInterfaceCode(Utils.GP_FPKJ);
            jtb.getGlobalInfo().setRequestTime(now);
            jtb.getGlobalInfo().setDataExchangeId("DZFPQZ" + Utils.GP_FPKJ + Utils.formatToDay() + Utils.randNineData());
            jtb.getData().setContentKey(contentKey);
            jtb.getData().setContent(content);

            StringBuffer sb = new StringBuffer("");
            sb.append("{");
            sb.append("\"interface\":");
            sb.append(JSON.toJSONString(jtb));
            sb.append("}");

            String responeStr = RequestUtils.getHttpConnectResult(sb.toString(), config.getBlueUrl(), config.getKeyStoreFile(), config.getKeyStorePass());
            log.info("开票请求结果信息===={}", responeStr);
            JSONObject reJson = JSONObject.parseObject(responeStr);
            // 获取对应的相应信息
            String rsJson = reJson.get("interface").toString();
            // 响应信息转为实体类
            JsonToBean resEntity = JSONObject.parseObject(rsJson, JsonToBean.class);
            String resCode = resEntity.getReturnStateInfo().getReturnCode();

            invoiceRequest.setFpqqlsh(fpkj.getFPQQLSH());
            invoiceRequest.setReq(sb.toString());
            invoiceRequest.setHjje(hjje);
            invoiceRequest.setHjse(hjse);
            invoiceRequest.setCreateTime(new Date());
            invoiceRequest.setRes(responeStr);

            // 开票成功
            if ("0000".equals(resCode)){
                SimpleDateFormat kpsmf = new SimpleDateFormat("yyyyMMddHHmmss");
                String resContent = resEntity.getData().getContent();
                byte[] asBytes = Base64.getDecoder().decode(resContent);
                String rContent = new String(asBytes, "UTF-8");
                JSONObject jsonContent = JSONObject.parseObject(rContent);
                ResContent responseContent = JSONObject.parseObject(jsonContent.get("DATA").toString(), ResContent.class);
                invoiceRequest.setPdfUrl(responseContent.getPDF_URL());
                invoiceRequest.setInvoiceStatus("1");
                invoiceRequest.setRemarks("开票成功");
                invoiceRequest.setFpdm(responseContent.getFP_DM());
                invoiceRequest.setFphm(responseContent.getFP_HM());
                invoiceRequest.setKprq(responseContent.getKPRQ());
                invoiceRequest.setMakeInvoiceDate(kpsmf.parse(responseContent.getKPRQ()));
                invoiceRequest.setFiled4(String.valueOf(sl));

                Integer result =eleInvoiceService.insertInvoiceReq(invoiceRequest);
                if (result > 0) {
                    // 电子发票详情信息
                    BlueInvoiceDetailed blueInvoice=new BlueInvoiceDetailed();
                    blueInvoice.setXmsl(1);
                    blueInvoice.setFeeCode(feeItem.getId());
                    blueInvoice.setSl(sl);
                    blueInvoice.setSubjectCode(feeItem.getSubjectsCode());
                    blueInvoice.setUnitprice(new BigDecimal(invoiceRequest.getMoney()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                    blueInvoice.setXmjshj(new BigDecimal(invoiceRequest.getMoney()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                    blueInvoice.setXmmc(feeItem.getFeeName());
                    BigDecimal big = new BigDecimal(blueInvoice.getXmjshj()/(1+blueInvoice.getSl()));
                    Double income=big.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    Double tax=blueInvoice.getXmjshj()-income;
                    blueInvoice.setIncome(income);
                    blueInvoice.setTax(tax);
                    blueInvoice.setInvoiceRequestId(invoiceRequest.getId());
                    blueInvoice.setId(String.valueOf(IdWorker.getId()));
                    invoiceReqService.addRequestInfo(blueInvoice);

                    // 插入票据和票据信息表中
                    ChargeInvoice invoice = new ChargeInvoice();
                    invoice.setProjectId(invoiceRequest.getProjectId());
                    invoice.setInvoiceHm(invoiceRequest.getFphm());
                    invoice.setInvoiceDm(invoiceRequest.getFpdm());
                    invoice.setMakeInvoiceDate(kpsmf.parse(invoiceRequest.getKprq()));
                    invoice.setPayer(invoiceRequest.getGmfMc());
                    invoice.setMoney(invoiceRequest.getMoney());
                    invoice.setZjSkrq(new SimpleDateFormat("yyyyMMddHHmmss").parse(invoiceRequest.getKprq()));
                    invoice.setPayMethod(invoiceRequest.getPayMethod());
                    invoice.setInvoiceMan(config.getKpr());
                    invoice.setPayee(config.getKpr());
                    invoice.setAddress(invoiceRequest.getAddress());
                    invoice.setCustomerId(invoiceRequest.getCustomerId());
                    invoice.setPdfUrl((String)invoiceRequest.getPdfUrl());
                    invoice.setDelFlag("0");
                    invoice.setTicket(InvoiceTypeEnum.INVOICE_TYPE_ELE.getCode());  // 电子发票
                    // 查询发票号码和代码是否存在，存在不给继续插入
                    String  chargeInvoiceId = invoiceService.getIdByInvoice(invoiceRequest.getFphm(), invoiceRequest.getFpdm());
                    if (null == chargeInvoiceId){
                        invoiceService.save(invoice);
                        chargeInvoiceId = invoice.getId();
                        List<ChargeInvoiceInfo> infos = new ArrayList<ChargeInvoiceInfo>();
                        // 循环创建对应开票信息
                        for (COMMON_FPKJ_XMXX temp : xmxxList) {
                            ChargeInvoiceInfo info = new ChargeInvoiceInfo();
                            info.setId(String.valueOf(IdWorker.getId()));
                            info.setInvoiceId(chargeInvoiceId);
                            info.setInvoiceDm(invoiceRequest.getFpdm());
                            info.setInvoiceHm(invoiceRequest.getFphm());
                            info.setAbstractInfo("");
                            info.setAddress(invoiceRequest.getAddress());
                            info.setInvoiceObject(temp.getXMMC());
                            info.setNum(Integer.valueOf(temp.getXMSL()));
                            info.setUnitPrice(Double.valueOf(temp.getXMDJ()));
                            info.setMoney(Double.valueOf(temp.getSE()) + Double.valueOf(temp.getXMJE()));
                            info.setSubjectCode(temp.getXMMC());
                            info.setFeeitemId(temp.getBY2());
                            info.setRate(Double.valueOf(temp.getSL()));
                            info.setTax(Double.valueOf(temp.getSE()));
                            info.setRealMoney(Double.valueOf(temp.getXMJE()));
                            info.setDelFlag("0");
                            infos.add(info);
                        }
                        invoiceInfoService.insertInfos(infos);
                    }else {
                        logger.info("票据信息已存在，id ==={}", chargeInvoiceId);
                        return false;
                    }
                }
            } else {
                invoiceRequest.setInvoiceStatus("3");
                invoiceRequest.setRemarks("开票失败!");
                eleInvoiceService.insertInvoiceReq(invoiceRequest);
                return true;
            }
        }else {
            // 获取账单信息
            String projectName = invoiceReqService.getOidByRid(invoiceRequest.getRoomId(), "6");
            String floorRoomName = invoiceReqService.getOidByRid(invoiceRequest.getRoomId(), "7");
            String remark = "";
            if (floorRoomName.indexOf(projectName) != -1){
                remark = floorRoomName;
            }else {
                remark = projectName + floorRoomName;
            }
            List<ChargeBills> billsList = chargeBillsService.listByBills(billIds);
            String BZ = billsList.stream().map(n -> n.getZjCny()).collect(Collectors.joining(">"));
            BZ = BZ + "\n" + remark + "\n" + PayModeEnum.getDesc(invoiceRequest.getPayMode());
            fpkj.setBZ(BZ);

            // 整合相同价格账单 票据里同单价计算份数
            List<ChargeBills> samePriceBills = new ArrayList<>();
            for (ChargeBills bill : billsList) {
                boolean flag = false;
                List<String> zys = new ArrayList<String>();
                String cny = bill.getZjCny();
                // 循环遍历查询相同的收费项目下，相同的金额下拼接成请求详细参数
                for (ChargeBills b : samePriceBills) {
                    if (bill.getFeeitemId().equals(b.getFeeitemId()) && bill.getDue().compareTo(b.getDue()) == 0) {
//                        zys.add(b.getZjCny());
                        cny += "," + b.getZjCny();
                        b.setNum(b.getNum()+1);
                        b.setZjCny(cny);
                        flag = true;
                    }
                }
                if (!flag && bill.getDue().compareTo(BigDecimal.ZERO)>0) {
                    samePriceBills.add(bill);
                }
            }
            if (samePriceBills.size() == 1){
                COMMON_FPKJ_XMXX xmxx = new COMMON_FPKJ_XMXX();
                ChargeBills bills = samePriceBills.get(0);
                // 摘要
                if (StringUtils.isNotEmpty(bills.getZjCny())){
                    String cnys[] = bills.getZjCny().split(",");
                    String newcnys[] = StringUtils.buffSort(cnys);
                    xmxx.setBY1(newcnys[0] + ">" + newcnys[newcnys.length - 1]);
                }
                // 税率
                sl = bills.getTaxRate()/100;
                xmxx.setSL(String.valueOf(sl));
                xmxx.setXMDJ(bills.getDue().toString());
                // 0 正常行、1 折扣行、2 被 折扣行
                xmxx.setFPHXZ("0");
                xmxx.setSPBM(bills.getMaintenanceCost());
                xmxx.setXMSL(String.valueOf(bills.getNum()));
                xmxx.setXMMC(bills.getFeeName());
                // 不含税金额
                Double realjesum = new BigDecimal(invoiceRequest.getMoney() / (1 + sl))
                        .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                // 不含税单价
                Double realdj = realjesum / Integer.valueOf(bills.getNum());
                // 税额
                Double se = new BigDecimal(invoiceRequest.getMoney() - realjesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                hjje = realjesum;
                hjse = se;
                xmxx.setXMJE(String.valueOf(realjesum));
                xmxx.setXMDJ(String.valueOf(realdj));
                xmxx.setSE(String.valueOf(se));
                xmxxList.add(xmxx);
                fpkj.setCOMMON_FPKJ_XMXX(xmxxList);

                /*
                 * 电子发票详情信息
                 * */
                BlueInvoiceDetailed blueInvoice=new BlueInvoiceDetailed();
                blueInvoice.setXmsl(bills.getNum());
                blueInvoice.setFeeCode(bills.getFeeitemId());
                blueInvoice.setSl(bills.getTaxRate()/100);
                blueInvoice.setSubjectCode(bills.getSubjectsCode());
                blueInvoice.setUnitprice(bills.getDue().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                blueInvoice.setXmjshj(new BigDecimal(invoiceRequest.getMoney()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                blueInvoice.setXmmc(bills.getFeeName());
                blueInvoice.setZy(bills.getZjCny());
                blueInvoiceList.add(blueInvoice);
            }else {
                // 累加金额
                double sum = 0;
                // 计算n-1项信息 避免四舍五入问题
                for (int i = 0; i < samePriceBills.size() -1; i++){
                    COMMON_FPKJ_XMXX xmxx = new COMMON_FPKJ_XMXX();
                    ChargeBills bills = samePriceBills.get(i);
                    // 摘要
                    if (StringUtils.isNotEmpty(bills.getZjCny())){
                        String cnys[] = bills.getZjCny().split(",");
                        String newcnys[] = StringUtils.buffSort(cnys);
                        xmxx.setBY1(newcnys[0] + ">" + newcnys[newcnys.length - 1]);
                    }
                    // 税率
                    sl = bills.getTaxRate()/100;
                    xmxx.setSL(String.valueOf(sl));
                    xmxx.setXMDJ(bills.getDue().toString());
                    // 0 正常行、1 折扣行、2 被 折扣行
                    xmxx.setFPHXZ("0");
                    xmxx.setSPBM(bills.getMaintenanceCost());
                    xmxx.setXMSL(String.valueOf(bills.getNum()));
                    xmxx.setXMMC(bills.getFeeName());
                    // 含税金额
                    Double jesum = new BigDecimal(bills.getNum()).multiply(bills.getDue()).setScale(2, BigDecimal.ROUND_HALF_UP)
                            .doubleValue();
                    sum = sum+jesum;
                    // 不含税金额
                    Double realjesum = new BigDecimal(jesum / (1 + sl))
                            .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    // 不含税单价
                    Double realdj = realjesum / Integer.valueOf(bills.getNum());
                    // 税额
                    Double se = new BigDecimal(jesum - realjesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    hjje += realjesum;
                    hjse += se;
                    xmxx.setXMJE(String.valueOf(realjesum));
                    xmxx.setXMDJ(String.valueOf(realdj));
                    xmxx.setSE(String.valueOf(se));
                    xmxxList.add(xmxx);
                    fpkj.setCOMMON_FPKJ_XMXX(xmxxList);

                    /*
                     * 电子发票详情信息
                     * */
                    BlueInvoiceDetailed blueInvoice=new BlueInvoiceDetailed();
                    blueInvoice.setXmsl(bills.getNum());
                    blueInvoice.setFeeCode(bills.getFeeitemId());
                    blueInvoice.setSl(bills.getTaxRate()/100);
                    blueInvoice.setSubjectCode(bills.getSubjectsCode());
                    blueInvoice.setUnitprice(bills.getDue().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                    blueInvoice.setXmjshj(new BigDecimal(invoiceRequest.getMoney()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                    blueInvoice.setXmmc(bills.getFeeName());
                    blueInvoice.setZy(bills.getZjCny());
                    blueInvoiceList.add(blueInvoice);
                }
                COMMON_FPKJ_XMXX xmxx = new COMMON_FPKJ_XMXX();
                ChargeBills lastBills = samePriceBills.get(samePriceBills.size() - 1);
                // 摘要
                if (StringUtils.isNotEmpty(lastBills.getZjCny())){
                    String cnys[] = lastBills.getZjCny().split(",");
                    String newcnys[] = StringUtils.buffSort(cnys);
                    xmxx.setBY1(newcnys[0] + ">" + newcnys[newcnys.length - 1]);
                }
                // 税率
                sl = lastBills.getTaxRate()/100;
                xmxx.setSL(String.valueOf(sl));
                xmxx.setXMDJ(lastBills.getDue().toString());
                // 0 正常行、1 折扣行、2 被 折扣行
                xmxx.setFPHXZ("0");
                xmxx.setSPBM(lastBills.getMaintenanceCost());
                xmxx.setXMSL(String.valueOf(lastBills.getNum()));
                xmxx.setXMMC(lastBills.getFeeName());
                // 含税金额
                Double jesum = new BigDecimal(invoiceRequest.getMoney() - sum).setScale(2, BigDecimal.ROUND_HALF_UP)
                        .doubleValue();
                // 不含税金额
                Double realjesum = new BigDecimal(jesum / (1 + sl))
                        .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                // 不含税单价
                Double realdj = realjesum / Integer.valueOf(lastBills.getNum());
                // 税额
                Double se = new BigDecimal(jesum - realjesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                hjje += realjesum;
                hjse += se;
                xmxx.setXMJE(String.valueOf(realjesum));
                xmxx.setXMDJ(String.valueOf(realdj));
                xmxx.setSE(String.valueOf(se));
                xmxxList.add(xmxx);
                fpkj.setCOMMON_FPKJ_XMXX(xmxxList);

                /*
                 * 电子发票详情信息
                 * */
                BlueInvoiceDetailed blueInvoice=new BlueInvoiceDetailed();
                blueInvoice.setXmsl(lastBills.getNum());
                blueInvoice.setFeeCode(lastBills.getFeeitemId());
                blueInvoice.setSl(lastBills.getTaxRate()/100);
                blueInvoice.setSubjectCode(lastBills.getSubjectsCode());
                blueInvoice.setUnitprice(lastBills.getDue().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                blueInvoice.setXmjshj(new BigDecimal(invoiceRequest.getMoney() - sum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                blueInvoice.setXmmc(lastBills.getFeeName());
                blueInvoice.setZy(lastBills.getZjCny());
                blueInvoiceList.add(blueInvoice);

            }
            // 合计金额 税额
            fpkj.setHJJE(String.valueOf(new BigDecimal(hjje).setScale(2, BigDecimal.ROUND_HALF_UP)));
            fpkj.setHJSE(String.valueOf(new BigDecimal(hjse).setScale(2, BigDecimal.ROUND_HALF_UP)));

            SimpleDateFormat smf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String now = smf.format(new Date());
            // 请求开票的JSON
            JsonRootBean jrb = new JsonRootBean();
            jrb.setREQUEST_COMMON_FPKJ(fpkj);
            String content = JSON.toJSONString(jrb);
            logger.info("发票请求报文实体类===={}", content);
            content = new BASE64Encoder().encodeBuffer(content.getBytes("UTF-8"));
            content = content.replaceAll("\r\n", "").replaceAll("\n", "");//json的报文不允许有换行，base64会产生。因此此处做去换行处理。
            String contentSha256 = Sha256Utils.SHA256Encrypt(content.getBytes("UTF-8"));
            String contentKey = MyAES.encryptBASE64(MyAES.encrypt(contentSha256.getBytes("UTF-8"), config.getContentPassword())).replaceAll("\r\n", "").replaceAll("\n", "");

            // 发票请求通用报文
            JsonToBean jtb = new JsonToBean();
            jtb.getGlobalInfo().setAppId(config.getAppid());
            jtb.getGlobalInfo().setInterfaceCode(Utils.GP_FPKJ);
            jtb.getGlobalInfo().setRequestTime(now);
            jtb.getGlobalInfo().setDataExchangeId("DZFPQZ" + Utils.GP_FPKJ + Utils.formatToDay() + Utils.randNineData());
            jtb.getData().setContentKey(contentKey);
            jtb.getData().setContent(content);

            StringBuffer sb = new StringBuffer("");
            sb.append("{");
            sb.append("\"interface\":");
            sb.append(JSON.toJSONString(jtb));
            sb.append("}");

            log.info("发票请求报文===={}", sb.toString());
            String responeStr = RequestUtils.getHttpConnectResult(sb.toString(), config.getBlueUrl(), config.getKeyStoreFile(), config.getKeyStorePass());
            log.info("开票请求结果信息===={}", responeStr);
            JSONObject reJson = JSONObject.parseObject(responeStr);
            // 获取对应的相应信息
            String rsJson = reJson.get("interface").toString();
            // 响应信息转为实体类
            JsonToBean resEntity = JSONObject.parseObject(rsJson, JsonToBean.class);
            String resCode = resEntity.getReturnStateInfo().getReturnCode();

            invoiceRequest.setFpqqlsh(fpkj.getFPQQLSH());
            invoiceRequest.setReq(sb.toString());
            invoiceRequest.setHjje(hjje);
            invoiceRequest.setHjse(hjse);
            invoiceRequest.setCreateTime(new Date());
            invoiceRequest.setRes(responeStr);

            // 开票成功
            if ("0000".equals(resCode)){
                SimpleDateFormat kpsmf = new SimpleDateFormat("yyyyMMddHHmmss");
                String resContent = resEntity.getData().getContent();
                byte[] asBytes = Base64.getDecoder().decode(resContent);
                String rContent = new String(asBytes, "UTF-8");
                JSONObject jsonContent = JSONObject.parseObject(rContent);
                ResContent responseContent = JSONObject.parseObject(jsonContent.get("DATA").toString(), ResContent.class);
                invoiceRequest.setPdfUrl(responseContent.getPDF_URL());
                invoiceRequest.setInvoiceStatus("1");
                invoiceRequest.setRemarks("开票成功");
                invoiceRequest.setFpdm(responseContent.getFP_DM());
                invoiceRequest.setFphm(responseContent.getFP_HM());
                invoiceRequest.setKprq(responseContent.getKPRQ());
                invoiceRequest.setMakeInvoiceDate(kpsmf.parse(responseContent.getKPRQ()));
                invoiceRequest.setFiled4(String.valueOf(sl));

                Integer result =eleInvoiceService.insertInvoiceReq(invoiceRequest);
                if (result > 0) {
                    try {
                        for(BlueInvoiceDetailed detail:blueInvoiceList) {
                            BigDecimal big = new BigDecimal(detail.getXmjshj()/(1+detail.getSl()));
                            Double income=big.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                            Double tax=detail.getXmjshj()-income;
                            detail.setIncome(income);
                            detail.setTax(tax);
                            detail.setInvoiceRequestId(invoiceRequest.getId());
                            detail.setId(String.valueOf(IdWorker.getId()));
                            invoiceReqService.addRequestInfo(detail);
                        }
                    }catch (Exception ex){
                        logger.info("电票详情插入异常！= {}", ex);
                        return false;
                    }

                    // 更新对应账单并更新发票信息
                    ChargeBills u = new ChargeBills();
                    u.setInvoiceNo(responseContent.getFP_HM());
                    u.setInvoiceGrnno(responseContent.getFP_DM());
                    u.setZjSkrq(kpsmf.parse(responseContent.getKPRQ()));
                    // 电票PDF地址
                    u.setDateRange(responseContent.getPDF_URL());
                    u.setPayuserName(config.getKpr());
                    u.setPayType(invoiceRequest.getPayMethod());
                    u.setMakeinvoiceDate(kpsmf.parse(responseContent.getKPRQ()));
                    u.setBillIds(billIds);
                    eleInvoiceService.updateBillsInvoice(u);

                    // 插入票据和票据信息表中
                    ChargeInvoice invoice = new ChargeInvoice();
                    invoice.setProjectId(invoiceRequest.getProjectId());
                    invoice.setInvoiceHm(invoiceRequest.getFphm());
                    invoice.setInvoiceDm(invoiceRequest.getFpdm());
                    invoice.setMakeInvoiceDate(kpsmf.parse(invoiceRequest.getKprq()));
                    invoice.setPayer(invoiceRequest.getGmfMc());
                    invoice.setMoney(invoiceRequest.getMoney());
                    invoice.setZjSkrq(new SimpleDateFormat("yyyyMMddHHmmss").parse(invoiceRequest.getKprq()));
                    invoice.setPayMethod(invoiceRequest.getPayMethod());
                    invoice.setInvoiceMan(config.getKpr());
                    invoice.setPayee(config.getKpr());
                    invoice.setAddress(invoiceRequest.getAddress());
                    invoice.setCustomerId(invoiceRequest.getCustomerId());
                    invoice.setPdfUrl((String)invoiceRequest.getPdfUrl());
                    invoice.setDelFlag("0");
                    invoice.setTicket(InvoiceTypeEnum.INVOICE_TYPE_ELE.getCode()); // 表示电子发票

                    // 查询发票号码和代码是否存在，存在不给继续插入
                    String  chargeInvoiceId = invoiceService.getIdByInvoice(invoiceRequest.getFphm(), invoiceRequest.getFpdm());
                    if (null == chargeInvoiceId){
                        invoiceService.save(invoice);
                        chargeInvoiceId = invoice.getId();
                        List<ChargeInvoiceInfo> infos = new ArrayList<ChargeInvoiceInfo>();
                        // 循环创建对应开票信息
                        for (COMMON_FPKJ_XMXX temp : xmxxList) {
                            ChargeInvoiceInfo info = new ChargeInvoiceInfo();
                            info.setId(String.valueOf(IdWorker.getId()));
                            info.setInvoiceId(chargeInvoiceId);
                            info.setInvoiceDm(invoiceRequest.getFpdm());
                            info.setInvoiceHm(invoiceRequest.getFphm());
                            info.setAbstractInfo(temp.getBY1());
                            info.setAddress(invoiceRequest.getAddress());
                            info.setInvoiceObject(temp.getXMMC());
                            info.setNum(Integer.valueOf(temp.getXMSL()));
                            info.setUnitPrice(Double.valueOf(temp.getXMDJ()));
                            info.setMoney(Double.valueOf(temp.getSE()) + Double.valueOf(temp.getXMJE()));
                            info.setSubjectCode(temp.getXMMC());
                            info.setFeeitemId(temp.getBY2());
                            info.setRate(Double.valueOf(temp.getSL()));
                            info.setTax(Double.valueOf(temp.getSE()));
                            info.setRealMoney(Double.valueOf(temp.getXMJE()));
                            info.setDelFlag("0");
                            infos.add(info);
                        }
                        invoiceInfoService.insertInfos(infos);
                    }else {
                        logger.info("票据信息已存在，id ==={}", chargeInvoiceId);
                        return false;
                    }
                }
            } else {
                invoiceRequest.setInvoiceStatus("3");
                invoiceRequest.setRemarks("开票失败!");
                eleInvoiceService.insertInvoiceReq(invoiceRequest);
                return false;
            }
        }
		return true;
	}

    /**
     * 发票红冲
     */
    @AutoLog(value = "发票红冲接口")
    @ApiOperation(value="发票红冲接口", notes="发票红冲接口")
    @PostMapping(value = "openRed")
    @ResponseBody
    public boolean openRed(@RequestBody String req, HttpServletRequest request) throws Exception{
        ChargeInvoiceRequest invoiceRequest = JSONObject.parseObject(req, ChargeInvoiceRequest.class);
        request.setAttribute("tenantId",invoiceRequest.getTenantId());
        logger.info("红冲发票订单号===={}", invoiceRequest.getFpqqlsh());
        String fpqqlsh = invoiceRequest.getFpqqlsh();
        invoiceRequest = invoiceReqService.getInfoByFpqqlsh(invoiceRequest.getFpqqlsh());
        if (null == invoiceRequest){
            logger.info("发票信息不存在");
            return false;
        }
        List<BlueInvoiceDetailed> detaileds = invoiceReqService.getInvoiceRequestInfo(invoiceRequest.getId());
        String BZ = "对应正数发票代码：" + invoiceRequest.getFpdm() + " 发票号码："+invoiceRequest.getFphm();

        InvoiceBwConfig config = comConfigMapper.get(invoiceRequest.getTenantId());
        if(null==config) {
            logger.info("项目暂无对应的配置");
            return false;
        }
        invoiceRequest.setId(String.valueOf(IdWorker.getId()));
        invoiceRequest.setDelFlag("0");
        invoiceRequest.setFplx("1");

        REQUEST_COMMON_FPKJ fpkj = new REQUEST_COMMON_FPKJ();
        // 1-税控盘 2-金税盘 3-UKEY 4-老税控服务器 5-新型税控服务器
        fpkj.setSBLX("4");
        fpkj.setFPQQLSH(ComUtil.createInvoiceSn(config.getProjectCode(), 3));
        fpkj.setYFP_DM(invoiceRequest.getFpdm());
        fpkj.setYFP_HM(invoiceRequest.getFphm());
        // 026 增值税普票(电票) 004 增值税专票(纸票) 028 增值税专票(电票) 007 增值税普票(纸票) 025 增值税普票(卷票)
        fpkj.setFPLXDM("026");
        // 0-蓝字发票；1-红字发票
        fpkj.setKPLX("1");
        // 0：普通征税 1：减按计征 2：差额征税
        fpkj.setZSFS("0");
        fpkj.setXSF_NSRSBH(config.getXsfNsrsbh());
        fpkj.setXSF_MC(config.getXsfMc());
        fpkj.setXSF_DZDH(config.getXsfDzdh());
        fpkj.setXSF_YHZH(config.getXsfYhzh());
        String tel = "";
        String address = "";

        if (StringUtils.isNotEmpty(invoiceRequest.getEin())) {
            // 税号
            String ein = invoiceRequest.getEin().replaceAll(" ", "");
            fpkj.setGMF_NSRSBH(ein);
        }
        if (StringUtils.isNotEmpty(invoiceRequest.getTel()) && this.isPhone(invoiceRequest.getTel())) {
            tel = invoiceRequest.getTel();
            fpkj.setGMF_SJH(tel);
        }
        if (StringUtils.isNotEmpty(invoiceRequest.getEmail())){
            String email = invoiceRequest.getEmail().replaceAll(" ", "");
            if (this.isEmail(email)) fpkj.setGMF_DZYX(email);
        }
        if (StringUtils.isNotEmpty(invoiceRequest.getAccount())) {
            fpkj.setGMF_YHZH(invoiceRequest.getAccount());
        }
        if (StringUtils.isNotEmpty(address)) {
            address = invoiceRequest.getAddress();
        }

        fpkj.setGMF_MC(invoiceRequest.getGmfMc());
        fpkj.setGMF_DZDH(address + " " + tel);
        fpkj.setKPR(config.getKpr());
        fpkj.setSKR(config.getKpr());
        fpkj.setFHR(config.getFhr());
        fpkj.setJSHJ(String.valueOf(new BigDecimal(0-invoiceRequest.getMoney()).setScale(2, BigDecimal.ROUND_HALF_UP)));

        double hjse = 0.0; // 合计税额
        double hjje = 0.0; // 合计金额
        double sl = 0.0; // 税率
        // 商品信息
        List<COMMON_FPKJ_XMXX> xmxxList = new ArrayList<>();
        // 无账单 月卡、水电费开票
        if (StringUtils.isEmpty(invoiceRequest.getBillIds())) {
            COMMON_FPKJ_XMXX xmxx = new COMMON_FPKJ_XMXX();
            // TODO
            ChargeFeeitem feeItem = feeItemService.getFeeitemById(invoiceRequest.getFeeitemId());
            if (null == feeItem) {
                logger.info("无效的收费项==={}", invoiceRequest.getFeeitemId());
                return false;
            }
            sl = (double) feeItem.getTaxRate() / 100;
            xmxx.setSL(String.valueOf(sl));
            xmxx.setBY2(feeItem.getId());
            // 0 正常行、1 折扣行、2 被 折扣行
            xmxx.setFPHXZ("0");
            xmxx.setXMSL("-1");
            // 不含税金额
            Double realjesum = new BigDecimal(invoiceRequest.getMoney() / (1 + sl))
                    .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            // 不含税单价
            Double realdj = realjesum;
            // 税额
            Double se = new BigDecimal(invoiceRequest.getMoney() - realjesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            hjje = realjesum;
            hjse = se;
            xmxx.setXMJE(String.valueOf(-realjesum));
            xmxx.setXMDJ(String.valueOf(realdj));
            xmxx.setSE(String.valueOf(0-se));
            xmxx.setSPBM(feeItem.getMaintenanceCost());
            xmxx.setXMMC(feeItem.getFeeName());
            xmxxList.add(xmxx);
            fpkj.setCOMMON_FPKJ_XMXX(xmxxList);
            // 合计金额 税额
            fpkj.setHJJE(String.valueOf(new BigDecimal(0-hjje).setScale(2, BigDecimal.ROUND_HALF_UP)));
            fpkj.setHJSE(String.valueOf(new BigDecimal(0-hjse).setScale(2, BigDecimal.ROUND_HALF_UP)));

        }else {
            // 获取账单信息
            List<String> billIds = Arrays.asList(invoiceRequest.getBillIds().split(","));
            List<ChargeBills> billsList = chargeBillsService.listByBills(billIds);
            // 整合相同价格账单 票据里同单价计算份数
            List<ChargeBills> samePriceBills = new ArrayList<>();
            for (ChargeBills bill : billsList) {
                boolean flag = false;
                List<String> zys = new ArrayList<String>();
                String cny = bill.getZjCny();
                // 循环遍历查询相同的收费项目下，相同的金额下拼接成请求详细参数
                for (ChargeBills b : samePriceBills) {
                    if (bill.getFeeitemId().equals(b.getFeeitemId()) && bill.getDue().compareTo(b.getDue()) == 0) {
//                        zys.add(b.getZjCny());
                        cny += "," + b.getZjCny();
                        b.setNum(b.getNum() + 1);
                        b.setZjCny(cny);
                        flag = true;
                    }
                }
                if (!flag && bill.getDue().compareTo(BigDecimal.ZERO)>0) {
                    samePriceBills.add(bill);
                }
            }
            if (samePriceBills.size() == 1) {
                COMMON_FPKJ_XMXX xmxx = new COMMON_FPKJ_XMXX();
                ChargeBills bills = samePriceBills.get(0);
                // 税率
                sl = bills.getTaxRate() / 100;
                xmxx.setSL(String.valueOf(sl));
                xmxx.setXMDJ(bills.getDue().toString());
                // 0 正常行、1 折扣行、2 被 折扣行
                xmxx.setFPHXZ("0");
                xmxx.setSPBM(bills.getMaintenanceCost());
                xmxx.setXMSL(String.valueOf(-bills.getNum()));
                xmxx.setXMMC(bills.getFeeName());
                // 不含税金额
                Double realjesum = new BigDecimal(invoiceRequest.getMoney() / (1 + sl))
                        .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                // 不含税单价
                Double realdj = realjesum / Integer.valueOf(bills.getNum());
                // 税额
                Double se = new BigDecimal(invoiceRequest.getMoney() - realjesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                hjje = realjesum;
                hjse = se;
                xmxx.setXMJE(String.valueOf(-realjesum));
                xmxx.setXMDJ(String.valueOf(realdj));
                xmxx.setSE(String.valueOf(0-se));
                xmxxList.add(xmxx);
                fpkj.setCOMMON_FPKJ_XMXX(xmxxList);
            } else {
                // 累加金额
                double sum = 0;
                // 计算n-1项信息 避免四舍五入问题
                for (int i = 0; i < samePriceBills.size() -1; i++){
                    COMMON_FPKJ_XMXX xmxx = new COMMON_FPKJ_XMXX();
                    ChargeBills bills = samePriceBills.get(i);
                    // 摘要
                    if (StringUtils.isNotEmpty(bills.getZjCny())){
                        String cnys[] = bills.getZjCny().split(",");
                        String newcnys[] = StringUtils.buffSort(cnys);
                        xmxx.setBY1(newcnys[0] + ">" + newcnys[newcnys.length - 1]);
                    }
                    // 税率
                    sl = bills.getTaxRate()/100;
                    xmxx.setSL(String.valueOf(sl));
                    xmxx.setXMDJ(bills.getDue().toString());
                    // 0 正常行、1 折扣行、2 被 折扣行
                    xmxx.setFPHXZ("0");
                    xmxx.setSPBM(bills.getMaintenanceCost());
                    xmxx.setXMSL(String.valueOf(0-bills.getNum()));
                    xmxx.setXMMC(bills.getFeeName());
                    // 含税金额
                    Double jesum = new BigDecimal(bills.getNum()).multiply(bills.getDue()).setScale(2, BigDecimal.ROUND_HALF_UP)
                            .doubleValue();
                    sum = sum+jesum;
                    // 不含税金额
                    Double realjesum = new BigDecimal(jesum / (1 + sl))
                            .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    // 不含税单价
                    Double realdj = realjesum / Integer.valueOf(bills.getNum());
                    // 税额
                    Double se = new BigDecimal(jesum - realjesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    hjje += realjesum;
                    hjse += se;
                    xmxx.setXMJE(String.valueOf(0-realjesum));
                    xmxx.setXMDJ(String.valueOf(realdj));
                    xmxx.setSE(String.valueOf(0-se));
                    xmxxList.add(xmxx);
                    fpkj.setCOMMON_FPKJ_XMXX(xmxxList);
                }
                COMMON_FPKJ_XMXX xmxx = new COMMON_FPKJ_XMXX();
                ChargeBills lastBills = samePriceBills.get(samePriceBills.size() - 1);
                // 摘要
                if (StringUtils.isNotEmpty(lastBills.getZjCny())){
                    String cnys[] = lastBills.getZjCny().split(",");
                    String newcnys[] = StringUtils.buffSort(cnys);
                    xmxx.setBY1(newcnys[0] + ">" + newcnys[newcnys.length - 1]);
                }
                // 税率
                sl = lastBills.getTaxRate()/100;
                xmxx.setSL(String.valueOf(sl));
                xmxx.setXMDJ(lastBills.getDue().toString());
                // 0 正常行、1 折扣行、2 被 折扣行
                xmxx.setFPHXZ("0");
                xmxx.setSPBM(lastBills.getMaintenanceCost());
                xmxx.setXMSL(String.valueOf(0-lastBills.getNum()));
                xmxx.setXMMC(lastBills.getFeeName());
                // 含税金额
                Double jesum = new BigDecimal(invoiceRequest.getMoney() - sum).setScale(2, BigDecimal.ROUND_HALF_UP)
                        .doubleValue();
                // 不含税金额
                Double realjesum = new BigDecimal(jesum / (1 + sl))
                        .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                // 不含税单价
                Double realdj = realjesum / Integer.valueOf(lastBills.getNum());
                // 税额
                Double se = new BigDecimal(jesum - realjesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                hjje += realjesum;
                hjse += se;
                xmxx.setXMJE(String.valueOf(0-realjesum));
                xmxx.setXMDJ(String.valueOf(realdj));
                xmxx.setSE(String.valueOf(0-se));
                xmxxList.add(xmxx);
                fpkj.setCOMMON_FPKJ_XMXX(xmxxList);
            }
            // 合计金额 税额
            fpkj.setHJJE(String.valueOf(new BigDecimal(0-hjje).setScale(2, BigDecimal.ROUND_HALF_UP)));
            fpkj.setHJSE(String.valueOf(new BigDecimal(0-hjse).setScale(2, BigDecimal.ROUND_HALF_UP)));
        }
        SimpleDateFormat smf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String now = smf.format(new Date());
        // 请求开票的JSON
        JsonRootBean jrb = new JsonRootBean();
        jrb.setREQUEST_COMMON_FPKJ(fpkj);
        String content = JSON.toJSONString(jrb);
        content = new BASE64Encoder().encodeBuffer(content.getBytes("UTF-8"));
        content = content.replaceAll("\r\n", "").replaceAll("\n", "");//json的报文不允许有换行，base64会产生。因此此处做去换行处理。
        String contentSha256 = Sha256Utils.SHA256Encrypt(content.getBytes("UTF-8"));
        String contentKey = MyAES.encryptBASE64(MyAES.encrypt(contentSha256.getBytes("UTF-8"), config.getContentPassword())).replaceAll("\r\n", "").replaceAll("\n", "");

        // 发票请求通用报文
        JsonToBean jtb = new JsonToBean();
        jtb.getGlobalInfo().setAppId(config.getAppid());
        jtb.getGlobalInfo().setInterfaceCode(Utils.GP_FPKJ);
        jtb.getGlobalInfo().setRequestTime(now);
        jtb.getGlobalInfo().setDataExchangeId("DZFPQZ" + Utils.GP_FPKJ + Utils.formatToDay() + Utils.randNineData());
        jtb.getData().setContentKey(contentKey);
        jtb.getData().setContent(content);

        StringBuffer sb = new StringBuffer("");
        sb.append("{");
        sb.append("\"interface\":");
        sb.append(JSON.toJSONString(jtb));
        sb.append("}");

        log.info("发票请求报文===={}", sb.toString());
        String responeStr = RequestUtils.getHttpConnectResult(sb.toString(), config.getBlueUrl(), config.getKeyStoreFile(), config.getKeyStorePass());
        log.info("开票请求结果信息===={}", responeStr);
        JSONObject reJson = JSONObject.parseObject(responeStr);
        // 获取对应的相应信息
        String rsJson = reJson.get("interface").toString();
        // 响应信息转为实体类
        JsonToBean resEntity = JSONObject.parseObject(rsJson, JsonToBean.class);
        String resCode = resEntity.getReturnStateInfo().getReturnCode();

        invoiceRequest.setFpqqlsh(fpkj.getFPQQLSH());
        // 开票成功
        if ("0000".equals(resCode)) {
            eleInvoiceService.deleteInvoiceReq(fpqqlsh);
            invoiceRequest.setMakeInvoiceDate(new Date());
            invoiceRequest.setInvoiceStatus("1");
            invoiceRequest.setKprq(null);
            invoiceRequest.setMoney(0-invoiceRequest.getMoney());
            invoiceRequest.setHjje(null);
            invoiceRequest.setHjse(null);
            invoiceRequest.setId(String.valueOf(IdWorker.getId()));
            invoiceRequest.setRemarks(BZ);
            eleInvoiceService.insertInvoiceReq(invoiceRequest);
            for (BlueInvoiceDetailed temp : detaileds){
                Double jshj = 0-temp.getXmjshj();
                BigDecimal big = new BigDecimal(jshj/(1+temp.getSl()));
                Double income=big.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                Double tax=jshj-income;
                temp.setXmjshj(jshj);
                temp.setIncome(income);
                temp.setTax(tax);
                temp.setInvoiceRequestId(invoiceRequest.getId());
                temp.setId(String.valueOf(IdWorker.getId()));
                invoiceReqService.addRequestInfo(temp);
            }
            return true;
        }
        return true;
    }

    @AutoLog(value = "是否生成电子发票")
    @ApiOperation(value="是否生成电子发票", notes="是否生成电子发票")
    @GetMapping(value = "/isOpenBlue")
    public boolean isOpenBlue(@RequestParam("sn") String sn) {
        if (StringUtils.isBlank(sn)) return false;
        ChargeInvoiceRequest invoiceRequest = invoiceReqService.getInfoByOrder(sn);
        if (invoiceRequest != null && InvoiceStatusEnum.INVOICE_STATUS_SUCCESS.getCode().equals(invoiceRequest.getInvoiceStatus())){
            return true;
        }
        return false;
    }

	//验证邮箱方法
    public static boolean isEmail(String string) {
	    if (string == null) return false;
	    String regEx1 = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
	    Pattern p;
	    Matcher m;
	    p = Pattern.compile(regEx1);
	    m = p.matcher(string);
	    if (m.matches()) return true;
	    else return false;
	}

	//验证手机号码
    public static boolean isPhone(String phone) {
	    String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
	    if (phone.length() != 11) {
	        return false;
	    } else {
	        Pattern p = Pattern.compile(regex);
	        Matcher m = p.matcher(phone);
	        boolean isMatch = m.matches();
	        return isMatch;
	    }
	}
}
